#!/usr/bin/env python
# -*- coding: utf-8 -*-
# time: 2022/10/19 15:11
# file: sys_user.py
# author: lotus163
from io import BytesIO
from typing import Optional

import xlsxwriter
from fastapi import APIRouter, Depends, Form, UploadFile, File
from fastapi.responses import StreamingResponse
import pandas as pd

from backend.api.system import user_profile
from backend.core.datascope import DataScope
from backend.core.deps import UserDepends, get_user_depends, get_user_depends_nolog
from backend.core.result import ResultRole, ResultData, ResultList, result_success, Result, ResultUser
from backend.core.security import hash_password
from backend.crud import UserDao, PostDao, RoleDao, DeptDao
from backend.schemas import SysUserSch
from backend.schemas.system.user import ChangeUserStatusForm, SysUserAdd, ResetPwdForm
from backend.service.system.dept import DeptService
from backend.service.system.user import UserService
from backend.service.system.user_post import UserPostService
from backend.service.system.user_role import UserRoleService
from backend.utils.form_util import get_form_dict
from backend.utils.string_util import get_array_by_str

router = APIRouter(prefix="/user", tags=["用户"])
router.include_router(user_profile.router)


@router.get("/", response_model=ResultUser, summary='获取用户')
async def get_user(user_depends: UserDepends = Depends(get_user_depends)):
    posts_sch = await PostDao.get_list_sch()
    roles = user_depends.login_user.user.roles
    return result_success(posts=posts_sch, roles=roles)


@router.put("", response_model=Result, summary='修改用户')
async def update_user(form: SysUserSch, user_depends: UserDepends = Depends(get_user_depends)):
    """

    :param form:
    :param user_depends:
    :return:
    """
    # 数据过滤,失败则抛出异常
    if not user_depends.login_user.user.admin:
        DataScope(user_depends.login_user.data_scope.roles_depts_users_ids).has_sope(form.userId)
    # 添加创建者
    user_db = await UserDao.get_db_or_none(userName=form.userName)
    form.updateBy = user_depends.login_user.user.userName
    await UserDao.update_sch(obj=user_db, **form.dict(exclude_none=True))
    await UserRoleService().update_roles_by_user_id(user_db.userId, form.roleIds)
    await UserPostService().update_posts_by_user_id(user_db.userId, form.postIds)
    return result_success()


@router.post("", response_model=Result, summary='新增用户')
async def add_user(form: SysUserAdd, user_depends: UserDepends = Depends(get_user_depends)):
    """
    先验证唯一性，再添加用户，同时添加角色和岗位，不许要检查权限
    :param form:
    :param user_depends:
    :return:
    """
    await UserService().check_user_unique(userName=form.userName, phonenumber=form.phonenumber, email=form.email)
    # 添加创建者
    form.createBy = user_depends.login_user.user.userName
    # 成功则增加了用户，失败，则抛出异常
    user_sch = await UserDao.add_sch(**form.dict(exclude_none=True))
    await UserRoleService().add_roles_by_user_id(user_sch.userId, form.roleIds)
    await UserPostService().add_posts_by_user_id(user_sch.userId, form.postIds)
    return result_success()


@router.put("/authRole", response_model=Result, summary='用户授权角色')
async def insert_auth_role(userId: int, roleIds: str, user_depends: UserDepends = Depends(get_user_depends)):
    role_ids = get_array_by_str(roleIds)
    # 数据权限
    if not user_depends.login_user.user.admin:
        role_ids = DataScope(user_depends.login_user.data_scope.user_roles_ids).get_sopes(role_ids)
    await UserRoleService().update_roles_by_user_id(userId, role_ids)
    return result_success()


@router.get("/authRole/{userId}", response_model=ResultRole, summary='根据用户编号获取授权角色')
async def get_auth_role(userId: int, user_depends: UserDepends = Depends(get_user_depends)):
    # 数据权限
    if not user_depends.login_user.user.admin:
        DataScope(user_depends.login_user.data_scope.roles_depts_users_ids).has_sope(userId)
    user_db = await UserDao.get_db_or_none(userId=userId)
    user_all_sch = await UserService().get_user_all_sch_by_db(user_db)
    roles_sch = await RoleDao.get_list_sch(roleId__in = user_all_sch.roleIds)
    return result_success(user=user_all_sch, roles=roles_sch)


@router.put("/changeStatus", response_model=Result, summary='状态修改')
async def change_status(form: ChangeUserStatusForm, user_depends: UserDepends = Depends(get_user_depends)):
    # 数据过滤,失败则抛出异常
    if not user_depends.login_user.user.admin:
        DataScope(user_depends.login_user.data_scope.roles_depts_users_ids).has_sope(form.userId)
    user_db = await UserDao.get_db_or_none(userId=form.userId)
    await UserDao.update_sch(obj=user_db, **form.dict(exclude_none=True))
    return result_success()


@router.get("/deptTree", response_model=ResultData, summary='获取部门树列表')
async def get_user_dept_tree(user_depends: UserDepends = Depends(get_user_depends)):
    """不应该有权限要所有人都看到"""
    return result_success(data=await DeptService().get_dept_tree())


@router.post("/export", summary='导出用户')
async def export_users(pageNum: int = Form(...),
                       pageSize: int = Form(...),
                       user_depends: UserDepends = Depends(get_user_depends_nolog)):
    # excel_file_path = "./user_1669608679751.xlsx"
    # headers = {'Content-Disposition': 'attachment; filename="user_1669608679751.xlsx"'}
    # return FileResponse(excel_file_path, headers=headers)
    # 使用FileResponse，需要先保存，而使用StreamingResponse，不需要保存
    output = BytesIO()  # 在内存中创建一个缓存流
    workbook = xlsxwriter.Workbook(output)
    worksheet = workbook.add_worksheet()
    worksheet.write(0, 0, 'ISBN')
    worksheet.write(0, 1, 'Name')
    worksheet.write(0, 2, 'Takedown date')
    worksheet.write(0, 3, 'Last updated')
    workbook.close()
    output.seek(0)
    headers = {
        'Content-Disposition': 'attachment; filename="filename.xlsx"'
    }
    return StreamingResponse(output, headers=headers)


@router.post("/importData", response_model=Result, summary='导入用户')
async def import_user_data(file: UploadFile = File(...)):
    file_name = file.filename
    print(file_name)
    if file_name.endswith("txt"):
        contents = await file.read()
        print(str(contents, 'utf-8'))
    if file_name.endswith("xlsx"):
        contents = await file.read()
        df = pd.read_excel(contents,sheet_name="voc数据")
        print(df)
    return result_success()


@router.post("/importTemplate", summary='下载模板')
async def import_user_template(user_depends: UserDepends = Depends(get_user_depends_nolog)):
    output = BytesIO()  # 在内存中创建一个缓存流
    workbook = xlsxwriter.Workbook(output)
    worksheet = workbook.add_worksheet()
    worksheet.write(0, 0, 'ISBN')
    worksheet.write(0, 1, 'Name')
    worksheet.write(0, 2, 'Takedown date')
    worksheet.write(0, 3, 'Last updated')
    workbook.close()
    output.seek(0)

    headers = {
        'Content-Disposition': 'attachment; filename="filename.xlsx"'
    }
    return StreamingResponse(output, headers=headers)


@router.get("/list", response_model=ResultList[SysUserSch], summary='获取用户列表')
async def get_user_list(pageNum: int, pageSize: int,
                        userName: Optional[str] = None,
                        phonenumber: Optional[str] = None,
                        status: Optional[str] = None,
                        deptId:Optional[int] = None,
                        user_depends: UserDepends = Depends(get_user_depends)):
    # 时间
    start, end = user_depends.request_service.get_params_time()

    # 准备查询的参数
    form_dict = get_form_dict(form=SysUserAdd(userName=userName, phonenumber=phonenumber, status=status),
                              start=start,end=end,time_range="createTime__range")
    if deptId:
        # 查询部门
        dept_ids = await DeptService().get_dept_ids_and_children(deptId)
        form_dict["deptId__in"]=dept_ids
    # 数据权限
    if not user_depends.login_user.user.admin:
        form_dict["userId__in"] = user_depends.login_user.data_scope.roles_depts_users_ids
    # 查询
    users_sch = await UserDao.get_list_sch_page(pageSize=pageSize, pageNum=pageNum, **form_dict)
    total = await UserDao.get_list_count(**form_dict)
    return result_success(msg="查询成功", rows=users_sch, total=total)


@router.put("/resetPwd", response_model=Result, summary='重置密码', )
async def reset_password(form: ResetPwdForm, user_depends: UserDepends = Depends(get_user_depends)):
    # 检查权限
    if not user_depends.login_user.user.admin:
        DataScope(user_depends.login_user.data_scope.roles_depts_users_ids).has_sope(form.userId)
    user_db = await UserDao.get_db_or_none(userId=form.userId)
    await UserDao.update_db(user_db, password=hash_password(form.password))
    return result_success()


@router.delete("/{userIds}", response_model=Result, summary='根据用户ids删除用户')
async def remove_users(userIds: str, user_depends: UserDepends = Depends(get_user_depends)):
    user_ids = get_array_by_str(userIds)
    for user_id in user_ids:
        await UserDao.delete_db(userId=user_id)
        await UserPostService().delete_posts_by_user_id(user_id)
        await UserRoleService().delete_roles_by_user_id(user_id)
    return result_success()


@router.get("/{userId}", response_model=ResultUser, summary='根据用户id获取详细信息')
async def get_user_by_id(userId: int, user_depends: UserDepends = Depends(get_user_depends)):
    # 数据权限
    if not user_depends.login_user.user.admin:
        DataScope(user_depends.login_user.data_scope.roles_depts_users_ids).has_sope(userId)
    user_db = await UserDao.get_sch_or_none(userId=userId)
    user_all_sch = await UserService().get_user_all_sch_by_db(user_db)
    posts_sch = await PostDao.get_list_sch()
    return result_success(data=user_all_sch, postIds=user_all_sch.postIds, posts=posts_sch,
                          roleIds=user_all_sch.roleIds, roles=user_all_sch.roles)
